package tr.com.netgis.web;

import static tr.com.netgis.util.Constants.METHOD_NAME_SET_LOCATION;
import static tr.com.netgis.util.Constants.METHOD_NAME_SET_LOCATIONS;
import static tr.com.netgis.util.Constants.NAMESPACE;
import static tr.com.netgis.util.Constants.SOAP_ACTION_SET_LOCATION;
import static tr.com.netgis.util.Constants.SOAP_ACTION_SET_LOCATIONS;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Date;

import org.kobjects.isodate.IsoDate;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.MarshalDate;
import org.ksoap2.serialization.MarshalFloat;
import org.ksoap2.serialization.PropertyInfo;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapPrimitive;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import org.kxml2.io.KXmlSerializer;
import org.xmlpull.v1.XmlSerializer;

import tr.com.cs.soap.NGIsoDate;
import tr.com.cs.soap.NGMarshalDate;
import tr.com.netgis.pojo.DeviceData;
import android.util.Log;

public class WebServisCaller {

    /**
     * drs.setLocation(ar2.adi, ar2.Y, ar2.X, DateTime.Now, "25", "YAZILIM", "SON_YERLER.BAGLANTI1.SON_YERLER", "", null);
	 * bu satırda sırayla aracın adı, koordinatları, bildirimin saati, hız,araç grubu, FAD, status ve namevalue collection bilgilerinin örnek kullanımı var.
	 * Test amaçlı olarak "SON_YERLER.BAGLANTI1.SON_YERLER" stringi gönderilirse VT’de son yerler tablosuna veriyi kaydeder.
	 * Verinin kaydedilip edilmediğini de MOBIZ veritabanındaki tabloları kontrol ederek görebilirsin.
	 * Ben ilk fırsatta dokumantasyonu ornek input outputlar ile geliştireceğim. Şimdilik bu şekilde devam edebiliriz.
	 * Koordinat bilgisi yollarken ondalık ayracı nokta olmalı aksi takdirde string double çevrimleri hata verebilir.
     */
	public static SetLocationResponse callWebService(SetLocationRequest setLocationRequest) {
		SetLocationResponse response = null;
		String message = "";
		try {
			SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME_SET_LOCATION);
	
			SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
					SoapEnvelope.VER11);	
			envelope.dotNet = true;
			envelope.setOutputSoapObject(request);

			System.out.println(NGIsoDate.dateToString((Date) new Date(), IsoDate.DATE_TIME));
			
			
			request.addProperty(setLocationRequest.getPropertyInfo(SetLocationRequest.P_DEVICE_CODE));
			request.addProperty(setLocationRequest.getPropertyInfo(SetLocationRequest.P_LAT));
			request.addProperty(setLocationRequest.getPropertyInfo(SetLocationRequest.P_LON));
			request.addProperty(setLocationRequest.getPropertyInfo(SetLocationRequest.P_TARIH_SAAT));
			request.addProperty(setLocationRequest.getPropertyInfo(SetLocationRequest.P_SPEED));
			request.addProperty(setLocationRequest.getPropertyInfo(SetLocationRequest.P_STATUS));
			
			Log.d("REQUEST", setLocationRequest == null ? "null" : setLocationRequest.toString());
			
			registerDataTypes(envelope);
		
			registerDataTypes(envelope);
			String xml = new String(createRequestData(envelope));
			System.out.println(xml);
			
			HttpTransportSE androidHttpTransport = new HttpTransportSE(setLocationRequest.getServerUrl());
			androidHttpTransport.debug = true;
			androidHttpTransport.call(SOAP_ACTION_SET_LOCATION, envelope);
			Object result = (Object) envelope.getResponse();
	
			if (result instanceof SoapPrimitive) {
				SoapPrimitive soapResult = (SoapPrimitive) result;
				message = soapResult.toString();
				System.out.println(message);
				response = new SetLocationResponse(message);
			} else if (result instanceof String []) {
				String[] results = (String[]) result;
				message =  results[0] + "\n";
				response = new SetLocationResponse(message);
			} else {
				response = new SetLocationResponse(result.toString());
			}
		} catch (Exception e) {
			e.printStackTrace();
			response = new SetLocationResponse(e);
			response.setExceptionString(e.getClass() + "\n" + e.getMessage());
		}
		setLocationRequest.getHandler().call(response);
		return response;
	}
	
	public static SetLocationsResponse callWebService(SetLocationsRequest setLocationsRequest) {
		SetLocationsResponse response = null;
		try {
			SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME_SET_LOCATIONS);
			
			SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
					SoapEnvelope.VER11);
			envelope.dotNet = true;
			envelope.setOutputSoapObject(request);
			envelope.addMapping(NAMESPACE, DeviceData.class.getSimpleName(), DeviceData.class);
			envelope.implicitTypes = true;
			
			PropertyInfo pi = setLocationsRequest.getPropertyInfo(SetLocationsRequest.P_DATA_PACKAGE);			
			request.addProperty(pi); 
			
			registerDataTypes(envelope);
			String xml = new String(createRequestData(envelope));
			System.out.println(xml);
			
			HttpTransportSE androidHttpTransport = new HttpTransportSE(setLocationsRequest.getServerUrl());
			androidHttpTransport.debug = true;
			androidHttpTransport.call(SOAP_ACTION_SET_LOCATIONS, envelope);
	
			Object result = (Object) envelope.getResponse();
	
			String message = "";
			if (result instanceof SoapPrimitive) {
				SoapPrimitive soapResult = (SoapPrimitive) result;
				message = soapResult.toString();
				System.out.println(message);
				response = new SetLocationsResponse(message);
			} else if (result instanceof String []) {
				String[] results = (String[]) result;
				message =  results[0] + "\n";
				response = new SetLocationsResponse(message);
			} else {
				response = new SetLocationsResponse(result.toString());
			}
		} catch (Exception e) {
			e.printStackTrace();
			response = new SetLocationsResponse(e);
			response.setExceptionString(e.getClass() + "\n" + e.getMessage());
		}
		setLocationsRequest.getHandler().call(response);
		return response;
	}
	
	public static SendMessageResponse callWebService(SendMessageRequest sendMessageRequest) {
		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		return new SendMessageResponse();
	}


	
	protected static byte[] createRequestData(SoapEnvelope envelope) throws IOException {
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
        bos.write("".getBytes());
        XmlSerializer xw = new KXmlSerializer();
        xw.setOutput(bos, null);
        envelope.write(xw);
        xw.flush();
        bos.write('\r');
        bos.write('\n');
        return bos.toByteArray();
	}
	
	private static void registerDataTypes (SoapSerializationEnvelope envelope) {
		
		MarshalFloat mf = new MarshalFloat();
		mf.register(envelope);
		
		MarshalDate md = new NGMarshalDate();
		md.register(envelope);
	}
}
